package com.jdj.framework.config.autoconfigure;

import com.jdj.framework.config.autoconfigure.properties.FrameworkCoreProperties;
import com.jdj.framework.config.autoconfigure.properties.MybatisProperties;
import com.jdj.framework.core.base.utils.JSONUtils;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;

/**
 *
 * Mybatis装载配置
 * 提示信息:
 * 1.AutoConfigureAfter:数据源自动配置装载之后再装载该配置
 *
 * MybatisAutoConfiguration
 * @author caijinbang
 * @date 2019-04-14 11:14
 */
@Configuration
@AutoConfigureAfter({DruidDataSourceAutoConfiguration.class})
@EnableConfigurationProperties({MybatisProperties.class})
public class MybatisAutoConfiguration {

    private static Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);


    private static final String COMPONENT_ID = "MyBatis";

    static final String SQL_SESSION_FACTORY = "sqlSessionFactory";

    @Autowired
    private MybatisProperties properties;

    @Autowired
    private FrameworkCoreProperties frameworkCoreProperties;

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory
    sqlSessionFactory(DataSource dataSource) {
        logger.info("顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶");
        LogUtils.configInfo(COMPONENT_ID, JSONUtils.objectToString(properties), logger);
        try {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            sessionFactory.setMapperLocations(properties.resolveMapperLocations());
            sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(properties.getConfigLocation()));
            LogUtils.instantiateInfo(COMPONENT_ID, SQL_SESSION_FACTORY, SqlSessionFactoryBean.class, logger);
            AutoInitManage.addInit(SQL_SESSION_FACTORY);
            return sessionFactory.getObject();
        } catch (Exception e) {
            throw new RuntimeException(LogUtils.instantiateFailureMsg(COMPONENT_ID, SQL_SESSION_FACTORY, SqlSessionFactoryBean.class, e, logger));
        }
    }

    /**
     * 检查Spring Bean 实例是否冲突
     *
     * @param bean 实例
     */
    @Bean
    @ConditionalOnBean({SqlSessionFactory.class})
    public String checkSqlSessionFactory(SqlSessionFactory bean) {
        if (bean != null && !AutoInitManage.isInit(SQL_SESSION_FACTORY)) {
            throw new RuntimeException(LogUtils.checkConflict(SqlSessionFactory.class, MybatisAutoConfiguration.class));
        }
        return null;
    }

    /**
     * 检查应用类型
     * @return
     */
    @Bean
    @ConditionalOnWebApplication
    public String checkApplicationType() {
        if (frameworkCoreProperties.getCheckApplicationTypeForService()) {
            throw new RuntimeException(LogUtils.onlyAllowedService("framework-boot-starter-dao"));
        }
        return null;
    }
}
